﻿// PL2318BDlg.cpp: 实现文件
//

#include "stdafx.h"
#include "CardTest.h"
#include "PL2318BDlg.h"
#include "afxdialogex.h"


// CPL2318BDlg 对话框

IMPLEMENT_DYNAMIC(CPL2318BDlg, CDialogEx)

CPL2318BDlg::CPL2318BDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG_PL2318B, pParent)
{

}

CPL2318BDlg::~CPL2318BDlg()
{
}

void CPL2318BDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_BASE_ADDRESS, m_editAddress);
	DDX_Control(pDX, IDC_STATIC_CARD_NO, m_lblCardNo);
	DDX_Control(pDX, IDC_BUTTON_START, m_btnStart);
	DDX_Control(pDX, IDC_STATIC_AI1, m_lblAI1);
	DDX_Control(pDX, IDC_STATIC_AI2, m_lblAI2);
	DDX_Control(pDX, IDC_STATIC_AI3, m_lblAI3);
	DDX_Control(pDX, IDC_STATIC_AI4, m_lblAI4);
	DDX_Control(pDX, IDC_STATIC_AI5, m_lblAI5);
	DDX_Control(pDX, IDC_STATIC_AI6, m_lblAI6);
	DDX_Control(pDX, IDC_STATIC_AI7, m_lblAI7);
	DDX_Control(pDX, IDC_STATIC_AI8, m_lblAI8);
	DDX_Control(pDX, IDC_STATIC_AI9, m_lblAI9);
	DDX_Control(pDX, IDC_STATIC_AI10, m_lblAI10);
	DDX_Control(pDX, IDC_STATIC_AI11, m_lblAI11);
	DDX_Control(pDX, IDC_STATIC_AI12, m_lblAI12);
	DDX_Control(pDX, IDC_STATIC_AI13, m_lblAI13);
	DDX_Control(pDX, IDC_STATIC_AI14, m_lblAI14);
	DDX_Control(pDX, IDC_STATIC_AI15, m_lblAI15);
	DDX_Control(pDX, IDC_STATIC_AI16, m_lblAI16);
	DDX_Control(pDX, IDC_RADIO1, m_btnGround);
	DDX_Control(pDX, IDC_RADIO3, m_btnRange);
	DDX_Control(pDX, IDC_EDIT_AO1, m_editAO1);
	DDX_Control(pDX, IDC_EDIT_AO2, m_editAO2);
	DDX_Control(pDX, IDC_EDIT_AO3, m_editAO3);
	DDX_Control(pDX, IDC_EDIT_AO4, m_editAO4);
	DDX_Control(pDX, IDC_RADIO6, m_btnAoRange);
	DDX_Control(pDX, IDC_COMBO_DIDO_MODE, m_didoMode);
	DDX_Control(pDX, IDC_RADIO8, m_btnD1);
	DDX_Control(pDX, IDC_RADIO9, m_btnD2);
	DDX_Control(pDX, IDC_RADIO10, m_btnD3);
	DDX_Control(pDX, IDC_RADIO11, m_btnD4);
	DDX_Control(pDX, IDC_RADIO12, m_btnD5);
	DDX_Control(pDX, IDC_RADIO13, m_btnD6);
	DDX_Control(pDX, IDC_RADIO14, m_btnD7);
	DDX_Control(pDX, IDC_RADIO15, m_btnD8);
	DDX_Control(pDX, IDC_RADIO16, m_btnD9);
	DDX_Control(pDX, IDC_RADIO17, m_btnD10);
	DDX_Control(pDX, IDC_RADIO18, m_btnD11);
	DDX_Control(pDX, IDC_RADIO19, m_btnD12);
	DDX_Control(pDX, IDC_RADIO20, m_btnD13);
	DDX_Control(pDX, IDC_RADIO21, m_btnD14);
	DDX_Control(pDX, IDC_RADIO22, m_btnD15);
	DDX_Control(pDX, IDC_RADIO23, m_btnD16);
	DDX_Control(pDX, IDC_RADIO24, m_btnD17);
	DDX_Control(pDX, IDC_RADIO25, m_btnD18);
	DDX_Control(pDX, IDC_RADIO26, m_btnD19);
	DDX_Control(pDX, IDC_RADIO27, m_btnD20);
	DDX_Control(pDX, IDC_RADIO28, m_btnD21);
	DDX_Control(pDX, IDC_RADIO29, m_btnD22);
	DDX_Control(pDX, IDC_RADIO30, m_btnD23);
	DDX_Control(pDX, IDC_RADIO31, m_btnD24);
	DDX_Control(pDX, IDC_STATIC_ERR_MSG, m_lblErrMsg);
}


BEGIN_MESSAGE_MAP(CPL2318BDlg, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_START, &CPL2318BDlg::OnBnClickedButtonStart)
	ON_BN_CLICKED(IDC_RADIO1, &CPL2318BDlg::OnBnClickedRadio1)
	ON_BN_CLICKED(IDC_RADIO2, &CPL2318BDlg::OnBnClickedRadio2)
	ON_CBN_SELCHANGE(IDC_COMBO_DIDO_MODE, &CPL2318BDlg::OnCbnSelchangeComboDidoMode)
	ON_CONTROL_RANGE(BN_CLICKED, IDC_RADIO8, IDC_RADIO31, &CPL2318BDlg::OnBnClickedRadio)
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CPL2318BDlg 消息处理程序

void CPL2318BDlg::EnableCtrl(BOOL bEnable)
{
	m_editAddress.EnableWindow(bEnable);

	m_btnGround.EnableWindow(bEnable);
	GetDlgItem(IDC_RADIO2)->EnableWindow(bEnable);

	m_btnRange.EnableWindow(bEnable);
	GetDlgItem(IDC_RADIO4)->EnableWindow(bEnable);
	GetDlgItem(IDC_RADIO5)->EnableWindow(bEnable);

	m_btnAoRange.EnableWindow(bEnable);
	GetDlgItem(IDC_RADIO7)->EnableWindow(bEnable);

	m_editAO1.EnableWindow(bEnable);
	m_editAO2.EnableWindow(bEnable);
	m_editAO3.EnableWindow(bEnable);
	m_editAO4.EnableWindow(bEnable);

	m_didoMode.EnableWindow(bEnable);
}

void CPL2318BDlg::ShowAiChans(BOOL bShow)
{
	m_lblAI9.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	m_lblAI10.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	m_lblAI11.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	m_lblAI12.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	m_lblAI13.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	m_lblAI14.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	m_lblAI15.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	m_lblAI16.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
}

void CPL2318BDlg::SetAiChanVal(int nChanIndex, double dblVal)
{
	CStatic* pAiCtrls[16] = {
		&m_lblAI1, &m_lblAI2, &m_lblAI3, &m_lblAI4, &m_lblAI5, &m_lblAI6, &m_lblAI7, &m_lblAI8,
		&m_lblAI9, &m_lblAI10, &m_lblAI11, &m_lblAI12, &m_lblAI13, &m_lblAI14, &m_lblAI15, &m_lblAI16
	};

	if (nChanIndex >= 1 && nChanIndex <= 16)
	{
		CString szVal;
		szVal.Format(L"AI%d:%.3f", nChanIndex, dblVal);
		pAiCtrls[nChanIndex - 1]->SetWindowText(szVal);
	}
}

void CPL2318BDlg::SetDioChanType()
{
	CButton* pButtons[24] = {
	&m_btnD1, &m_btnD2, &m_btnD3, &m_btnD4, &m_btnD5, &m_btnD6, &m_btnD7, &m_btnD8,
	&m_btnD9, &m_btnD10, &m_btnD11, &m_btnD12, &m_btnD13, &m_btnD14, &m_btnD15, &m_btnD16,
	&m_btnD17, &m_btnD18, &m_btnD19, &m_btnD20, &m_btnD21, &m_btnD22, &m_btnD23, &m_btnD24
	};

	for (int nChanIndex = 1; nChanIndex <= 24; nChanIndex++)
	{
		BOOL bTypeIn = IsDiChan(nChanIndex);

		CString szName;
		szName.Format(L"%d(D%s)", nChanIndex, bTypeIn ? L"I" : L"O");
		pButtons[nChanIndex - 1]->SetWindowText(szName);

		pButtons[nChanIndex - 1]->EnableWindow(!bTypeIn);
		if (bTypeIn)
		{
			pButtons[nChanIndex - 1]->SetCheck(0);
		}
	}
}

void CPL2318BDlg::SetDioChanVal(int nChanIndex, BOOL bVal)
{
	CButton* pButtons[24] = {
	&m_btnD1, &m_btnD2, &m_btnD3, &m_btnD4, &m_btnD5, &m_btnD6, &m_btnD7, &m_btnD8,
	&m_btnD9, &m_btnD10, &m_btnD11, &m_btnD12, &m_btnD13, &m_btnD14, &m_btnD15, &m_btnD16,
	&m_btnD17, &m_btnD18, &m_btnD19, &m_btnD20, &m_btnD21, &m_btnD22, &m_btnD23, &m_btnD24
	};

	if (nChanIndex >= 1 && nChanIndex <= 24)
	{
		if (IsDiChan(nChanIndex))
		{
			pButtons[nChanIndex - 1]->SetCheck(bVal);
		}
	}
}

BYTE CPL2318BDlg::GetDioCtrlVal(int nChanIndex)
{
	ASSERT(nChanIndex >= 1 && nChanIndex <= 24);

	CButton* pButtons[24] = {
		&m_btnD1, &m_btnD2, &m_btnD3, &m_btnD4, &m_btnD5, &m_btnD6, &m_btnD7, &m_btnD8,
		&m_btnD9, &m_btnD10, &m_btnD11, &m_btnD12, &m_btnD13, &m_btnD14, &m_btnD15, &m_btnD16,
		&m_btnD17, &m_btnD18, &m_btnD19, &m_btnD20, &m_btnD21, &m_btnD22, &m_btnD23, &m_btnD24
	};

	BYTE nVal = pButtons[nChanIndex - 1]->GetCheck() ? 1 : 0;

	return nVal;
}

BOOL CPL2318BDlg::IsDiChan(int nChanIndex)
{
	ASSERT(nChanIndex >= 1 && nChanIndex <= 24);

	return IPm511pf::IsDiChan((BYTE)m_didoMode.GetCurSel(), nChanIndex);
}


void CPL2318BDlg::OnBnClickedButtonStart()
{
	CString szErrMsg;
	BOOL bRet = TRUE;
	if (m_bRuning) // 正在运行，停止
	{
		KillTimer(1);
		bRet = m_card.CloseCard(szErrMsg);
		if (bRet)
		{
			m_lblCardNo.SetWindowText(L"板卡号：未知");
		}
	}
	else // 处于停止状态， 开始
	{
		// 基址
		ULONG nBaseAddr = 0;
		CString szAddr;
		m_editAddress.GetWindowText(szAddr);
		swscanf_s(szAddr, L"%X", &nBaseAddr);
		m_card.SetBaseAddress(nBaseAddr);
		// AI接地模式
		BYTE nGround = (m_btnGround.GetCheck() != 0) ? PM511PF_AI_GROUND_SINGLE : PM511PF_AI_GROUND_DOUBLE;
		m_card.SetAiGround(nGround);
		// AI量程
		BYTE nAiRange = PM511PF_AI_RANGLE_0_10V;
		CButton* pButton = (CButton*)GetDlgItem(IDC_RADIO4);
		if (pButton->GetCheck())
		{
			nAiRange = PM511PF_AI_RANGLE_N5_5V;
		}
		else
		{
			pButton = (CButton*)GetDlgItem(IDC_RADIO5);
			if (pButton->GetCheck())
				nAiRange = PM511PF_AI_RANGLE_N10_10V;
		}
		m_card.SetAiRange(nAiRange);
		// AO量程
		BYTE nAoRange = PM511PF_AO_RANGLE_0_10V;
		pButton = (CButton*)GetDlgItem(IDC_RADIO7);
		if (pButton->GetCheck())
		{
			nAoRange = PM511PF_AO_RANGLE_N10_10V;
		}
		m_card.SetAoRange(nAoRange);
		// DIO模式
		m_card.SetDigitalMode((BYTE)m_didoMode.GetCurSel());

		bRet = m_card.OpenCard(szErrMsg);
		if (bRet)
		{
			CString szCardNo;
			szCardNo.Format(L"板卡号：%lu", m_card.GetCardNo());
			m_lblCardNo.SetWindowText(szCardNo);
			SetTimer(1, 50, NULL);
		}
	}

	if (!bRet)
	{
		MessageBox(szErrMsg, L"测试PM511PF", MB_OK | MB_ICONEXCLAMATION);
		return;
	}

	m_bRuning = !m_bRuning;
	m_btnStart.SetWindowText(m_bRuning ? L"停止" : L"开始");

	EnableCtrl(!m_bRuning);
}

BOOL CPL2318BDlg::OnInitDialog()
{
	m_btnGround.SetCheck(BST_CHECKED);
	m_btnRange.SetCheck(BST_CHECKED);
	m_btnAoRange.SetCheck(BST_CHECKED);

	m_editAO1.SetWindowText(L"0");
	m_editAO2.SetWindowText(L"0");
	m_editAO3.SetWindowText(L"0");
	m_editAO4.SetWindowText(L"0");

	for (int i = 1; i <= 16; i++)
	{
		SetAiChanVal(i, 0);
	}

	SetDioChanType();

	for (int i = 0; i < 16; i++)
	{
		CString szModes[16] = {
			L"输出   输出       输出   输出",  /*0*/
			L"输出   输出       输出   输入",  /*1*/
			L"输出   输出       输入   输出",  /*2*/
			L"输出   输出       输入   输入",  /*3*/
			L"输出   输入       输出   输出",  /*4*/
			L"输出   输入       输出   输入",  /*5*/
			L"输出   输入       输入   输出",  /*6*/
			L"输出   输入       输入   输入",  /*7*/
			L"输入   输出       输出   输出",  /*8*/
			L"输入   输出       输出   输入",  /*9*/
			L"输入   输出       输入   输出",  /*10*/
			L"输入   输出       输入   输入",  /*11*/
			L"输入   输入       输出   输出",  /*12*/
			L"输入   输入       输出   输入",  /*13*/
			L"输入   输入       输入   输出",  /*14*/
			L"输入   输入       输入   输入"   /*15*/
		};

		m_didoMode.InsertString(-1, szModes[i]);
	}
	m_didoMode.SetCurSel(0);

	m_lblErrMsg.SetWindowText(L"");

	m_bRuning = FALSE;

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常:  OCX 属性页应返回 FALSE
}


void CPL2318BDlg::OnBnClickedRadio1()
{
	ShowAiChans(TRUE);
}


void CPL2318BDlg::OnBnClickedRadio2()
{
	ShowAiChans(FALSE);
}


void CPL2318BDlg::OnCbnSelchangeComboDidoMode()
{
	SetDioChanType();
}

void CPL2318BDlg::OnBnClickedRadio(UINT nID)
{
	CButton* pButton = (CButton*)GetDlgItem(nID);
	pButton->SetCheck(!pButton->GetCheck());
}

void CPL2318BDlg::OnTimer(UINT_PTR nIDEvent)
{
	if (nIDEvent == 1)
	{
		// 采集
		CString szError;
		if (!m_card.Input(szError))
		{
			m_lblErrMsg.SetWindowText(szError);
		}

		// 显示AI
		int nAiCount = m_btnGround.GetCheck() ? 16 : 8;
		for (int i = 1; i <= nAiCount; i++)
		{
			SetAiChanVal(i, m_card.GetAI(i));
		}

		// 显示DI
		for (int i = 1; i <= 24; i++)
		{
			SetDioChanVal(i, m_card.GetDI(i));
		}

		// 设置AO输出
		CString szVal;
		double dblVal = 0;

		m_editAO1.GetWindowText(szVal);
		dblVal = _wtof(szVal);
		m_card.SetAoVal(1, dblVal);

		m_editAO2.GetWindowText(szVal);
		dblVal = _wtof(szVal);
		m_card.SetAoVal(2, dblVal);

		m_editAO3.GetWindowText(szVal);
		dblVal = _wtof(szVal);
		m_card.SetAoVal(3, dblVal);

		m_editAO4.GetWindowText(szVal);
		dblVal = _wtof(szVal);
		m_card.SetAoVal(4, dblVal);

		// 设置DO输出
		for (int i = 1; i <= 24; i++)
		{
			m_card.SetDoVal(i, GetDioCtrlVal(i));
		}

		// 输出
		if (!m_card.Output(szError))
			m_lblErrMsg.SetWindowText(szError);
	}
}
